package com.github.aloxc.plugin.restplus.utils;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.aloxc.plugin.restplus.exception.JsonException;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author zhaow
 * @modify liyh
 */
public class JsonUtils {
    private static JsonFactory jsonFactory = new JsonFactory();

    private static ObjectMapper mapper = null;

    static {
        jsonFactory.configure(com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
        jsonFactory.configure(com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
        mapper = new ObjectMapper(jsonFactory);
    }

    private JsonUtils() {
    }


    /**
     * 将json转成java bean
     *
     * @param <T>   -- 多态类型
     * @param json  -- json字符串
     * @param clazz -- java bean类型(Class)
     * @return -- java bean对象RestRequestHistoryListener
     */
    public static <T> T toBean(String json, Class<T> clazz) {
        T rtv = null;
        try {
            rtv = mapper.readValue(json, clazz);
        } catch (Exception ex) {
            ex.printStackTrace();
            Log.log1(JsonUtils.class.getName()+"",json);
            throw new JsonException("json字符串转成java bean异常", ex);
        }
        return rtv;
    }

    /**
     * 将java bean转成json
     *
     * @param bean -- java bean
     * @param pretty
     * @return -- json 字符串
     */
    public static String toJson(Object bean,boolean pretty) {
        try {
            if(pretty) {
                return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(bean);
            }else {
                return mapper.writeValueAsString(bean);
            }
        } catch (JsonProcessingException e) {
            throw new JsonException("java bean转成json字符串异常", e);
        }
    }


    /**
     * 把数组类型的json转为list&ltBean&gt
     *
     * @param <T>   -- 多态类型
     * @param json  -- json字符串
     * @param clazz -- java bean类型(Class)
     * @return List&ltT&gt
     * @throws IllegalArgumentException 如果参数json为null,或者转换过程出错.
     */
    public static <T> List<T> toBeanList(String json, Class<T> clazz) {
        if (StringUtils.isEmpty(json)) {
            throw new JsonException("json can not null");
        }
        List<T> result = null;
        try {
            JsonNode jn = mapper.readTree(json);
            result = new ArrayList<>();
            if (jn.isArray()) {
                Iterator<JsonNode> iter = jn.iterator();
                while (iter.hasNext()) {
                    parseBeanAddToList(iter.next(), result, clazz);
                }
            } else {
                parseBeanAddToList(jn, result, clazz);
            }

        } catch (Throwable e) {
            Log.log1(JsonUtils.class.getName(),json);
            throw new JsonException("json字符串转成java List<bean>异常", e);
        }
        return result;
    }

    private static <T> void parseBeanAddToList(JsonNode js, List<T> list, Class<T> clazz) throws Throwable,
            IOException {
        T rtv = mapper.readValue(js.toString(), clazz);
        list.add(rtv);
    }


    public static String format(String str) {
        Object o = JsonUtils.toBean(str, Object.class);
        return JsonUtils.toJson(o,true);
    }
    public static boolean isJson(String targetStr) {
        try {
            JsonUtils.toBean(targetStr, Object.class);
            return true;
        } catch (Throwable ex) {
            return false;
        }
    }



}